package com.sz.app.edi.aspect;

import com.sz.app.edi.constants.EdiErrorCodes;
import com.sz.app.edi.base.entity.SynCompanyAccount;
import com.sz.app.edi.base.service.SynCompanyAccountService;
import com.sz.app.edi.rest.edi.token.dto.AuthDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.utils.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;

/**
 * Created by jifeixing on 4/10/17.
 */
//@Aspect
//@Component
public class WebServiceAspect {

    private final static Logger log = LoggerFactory.getLogger(WebServiceAspect.class);
    public static final String SERVICES_CUS_ORDER_SERVICE_TOKEN = "services/CusOrderService/token";

    @Autowired
    private SynCompanyAccountService synCompanyAccountService;

    @Before("execution(* com.sz.app.edi.service.order..*Service.*(..))")
    public void dBefore(JoinPoint joinPoint) throws Exception {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //用户请求的方法
        String servicePath = request.getRequestURI();
        String methodName = joinPoint.getSignature().getName();
        //获取请求参数
        Object[] args = joinPoint.getArgs();
        if (null != args && args.length > 0) {
            String params = args[0] + "";
            //客户访问ip
            String ip = request.getRemoteAddr();
            //是否生成token请求
            boolean isGenerateToken = isGenerateToken(servicePath + "/" + methodName);
            if (isGenerateToken) {
                //验证帐号
                AuthDto authDto = getApiKeySecurity(params, "apiKey", "securityKey", null, null);
                SynCompanyAccount synCompanyAccount = synCompanyAccountService.validAccount(authDto.getApiKey(), authDto.getSecurityKey());
                //验证ip
                CommonAuth.validIP(synCompanyAccount, ip);
            } else {
                //请求参数
                AuthDto authDto = getApiKeySecurity(params, null, null, "token", "funCode");
                if (null != authDto) {
                    //token有效性
                    SynCompanyAccount synCompanyAccount = synCompanyAccountService.validToken(authDto.getToken());
                    //验证ip
                    CommonAuth.validIP(synCompanyAccount, ip);
                    //判断用户是否有访问的权限
                    CommonAuth.validFunctionPermission(synCompanyAccount, authDto.getFunCode());
                } else {
                    //参数错误
                    throw Exceptions.bizException(EdiErrorCodes.ERROR_ARGUMENT);
                }
            }
        } else {
            //参数错误
            throw Exceptions.bizException(EdiErrorCodes.ERROR_ARGUMENT);
        }
    }

    /**
     * 是否换取token方法
     * @param requestUri
     * @return
     */
    private boolean isGenerateToken(String requestUri) {
        return (!StringUtils.isEmpty(requestUri) && SERVICES_CUS_ORDER_SERVICE_TOKEN.equals(requestUri));
    }

    /**
     * 获取用户apikey和apisecurity,token,funCode
     * @param data
     * @param apiKey
     * @param securityKey
     * @param token
     * @param funCode
     * @return
     */
    private AuthDto getApiKeySecurity(String data, String apiKey, String securityKey, String token, String funCode) {
        AuthDto authDto = new AuthDto();
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(new ByteArrayInputStream(data.getBytes("UTF-8")));
            //获取根节点
            Element root = document.getRootElement();
            if (!StringUtils.isEmpty(apiKey)) {
                //获取apiKey
                Element apiKeyElement = root.element(apiKey);
                if (null != apiKeyElement) {
                    authDto.setApiKey(apiKeyElement.getStringValue());
                }
            }
            if (!StringUtils.isEmpty(securityKey)) {
                //获取securityKey
                Element securityKeyElement = root.element(securityKey);
                if (null != securityKeyElement) {
                    authDto.setSecurityKey(securityKeyElement.getStringValue());
                }
            }
            if (!StringUtils.isEmpty(token)) {
                //获取token
                Element tokenElement = root.element(token);
                if (null != tokenElement) {
                    authDto.setToken(tokenElement.getStringValue());
                }
            }
            if (!StringUtils.isEmpty(funCode)) {
                //获取funCode
                Element funCodeElement = root.element(funCode);
                if (null != funCodeElement) {
                    authDto.setFunCode(funCodeElement.getStringValue());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return authDto;
    }
}
